import { _decorator, Component } from 'cc';
import { BattleSystem } from './battle/BattleSystem';
import { CommandParam, CommandParamMap } from './battle/Model';
import { CommandType } from './battle/Enums';
import { DEFAULT_COMMANDS } from './TestCmdLogs';
import { GameCore } from './core/game';
import { BattleScene } from './view/scene/BattleScene';
import { battleScene } from './view/scene/BattleSceneManager';
import { GameConfig } from './config';
import { TestBattleScript } from './TestBattleScript';
import { LOG } from './ConsoleLogCtrl';

// 确保可以访问全局 gc 对象
declare const gc: GameCore;

const { ccclass, property } = _decorator;

/**
 * 命令执行器
 * 用于执行预定义的命令队列
 */
@ccclass('CommandExecutor')
export class CommandExecutor extends Component {
    private _executionInterval: number = 100; // 回合之间的执行间隔(毫秒)

    public battleScene: BattleScene = null;

    private _battleSystem: BattleSystem = null;
    private _commandQueue: CommandParam<keyof CommandParamMap>[] = [];
    private _isExecuting: boolean = false;
    private _currentRound: number = 0; // 当前执行的回合
    private _currentRoundCommandIndex: number = 0; // 当前回合内的命令序号
    private _commandIdCounter: number = 0; // 命令ID计数器
    private _testBattleScript: TestBattleScript = null;

    /**
     * 手动启动命令执行
     */
    public startExecution() {
        // 脚本模式
        if (GameConfig.enableTestBattleScript) {
            LOG.log('TestBattleScript 脚本启动 - 脚本模式');
            this._testBattleScript = this.getComponent(TestBattleScript);
            if (this._testBattleScript) {
                this._testBattleScript.onTestBattleScriptStart();
            } else {
                LOG.error('未找到TestBattleScript组件');
            }
            return;
        }

        // 命令集模式
        if (GameConfig.enableCommandSet) {
            LOG.log('CommandExecutor 脚本启动 - 命令集模式');

            // 使用全局的战斗系统实例
            this._battleSystem = gc.battle;
            LOG.log('已获取全局战斗系统实例');

            // 直接使用默认命令数据
            let commands = [...DEFAULT_COMMANDS];

            // 根据GameConfig.enableReplay过滤命令
            if (!GameConfig.enableReplay) {
                commands = commands.filter(command => {
                    // 过滤掉end命令
                    if (command.type === CommandType.end) {
                        return false;
                    }
                    // 过滤掉第0回合的构建基地命令
                    if (command.type === CommandType.build && command.round === 0) {
                        return false;
                    }
                    return true;
                });
            }

            this._commandQueue = commands;
            LOG.log(`加载了 ${this._commandQueue.length} 条默认命令`);
            this.startExecutingCommands();
            return;
        }
    }

    /**
     * 开始执行命令队列
     */
    private startExecutingCommands() {
        if (this._isExecuting || this._commandQueue.length === 0) {
            return;
        }

        this._isExecuting = true;

        // 根据配置决定执行方式
        if (GameConfig.enableReplay) {
            // 回放模式：批量发送所有命令到战斗场景
            this.executeAllCommands();
        } else {
            // 逐步执行模式：逐个执行命令
            this.executeNextCommand();
        }
    }

    /**
     * 验证命令对象是否有效
     * @param command 要验证的命令对象
     * @returns 命令是否有效
     */
    private isValidCommand(command: any): boolean {
        // 检查必要字段
        if (!command || typeof command !== 'object') return false;
        if (!command.type || typeof command.type !== 'string') return false;
        if (!command.player || typeof command.player !== 'string') return false;
        if (!command.param || typeof command.param !== 'object') return false;

        // 根据命令类型检查其他必要字段
        switch (command.type) {
            case CommandType.init:
            case CommandType.move:
            case CommandType.attack:
            case CommandType.swap:
            case CommandType.build:
            case CommandType.end:
            case CommandType.heal:
            case CommandType.collect:
                return true;
            default:
                LOG.warn(`未知的命令类型: ${command.type}`);
                return false;
        }
    }

    /**
     * 执行下一条命令或命令组
     */
    private executeNextCommand() {
        // 检查命令队列是否为空
        if (this._commandQueue.length === 0) {
            LOG.log('所有命令已执行完毕');
            this._isExecuting = false;
            return;
        }

        // 获取队列中的第一条命令
        const firstCommand = this._commandQueue[0];
        const currentRound = firstCommand.round || 0;

        // 如果当前回合与上一个回合不同，则更新当前回合
        if (currentRound !== this._currentRound) {
            this._currentRound = currentRound;
            this._currentRoundCommandIndex = 0;
        }

        // 如果是init命令，使用单个命令执行方式
        if (firstCommand.type === CommandType.init) {
            this.executeSingleCommand();
        } else {
            // 其他命令使用批量执行方式
            this.executeRoundCommands();
        }
    }

    /**
     * 执行单个命令（用于init命令）
     */
    private executeSingleCommand() {
        const command = this._commandQueue.shift();
        this._currentRoundCommandIndex++;
        this._commandIdCounter++;

        // 验证命令是否有效
        if (!this.isValidCommand(command)) {
            LOG.error(`无效的命令对象:`, command);
            this.executeNextCommand();
            return;
        }

        // 执行单个命令
        try {
            const result = this._battleSystem.cmd(command);
            LOG.log(`执行单个命令: ${this._commandIdCounter} ${command.type}, 玩家:${command.player}, 回合:${command.round}, 结果: ${result.valid ? '成功' : '失败'}`);
        } catch (error) {
            LOG.error(`执行单个命令失败: ${this._commandIdCounter} ${command.type}, 玩家:${command.player}, 回合:${command.round}`, error);
        }

        // 继续执行下一条命令
        if (this._commandQueue.length > 0) {
            setTimeout(() => {
                this.executeNextCommand();
            }, this._executionInterval);
        }
    }

    /**
     * 执行回合命令（按玩家分组批量执行）
     */
    private executeRoundCommands() {
        const currentRound = this._commandQueue[0].round || 0;

        // 收集当前回合的所有命令，按玩家分组
        const playerCommands = new Map<string, CommandParam<keyof CommandParamMap>[]>();

        // 提取当前回合的所有命令
        while (this._commandQueue.length > 0 && (this._commandQueue[0].round || 0) === currentRound) {
            const command = this._commandQueue.shift();

            if (!this.isValidCommand(command)) {
                LOG.error(`无效的命令对象:`, command);
                continue;
            }

            const player = command.player;
            if (!playerCommands.has(player)) {
                playerCommands.set(player, []);
            }
            playerCommands.get(player).push(command);
        }

        // 为每个玩家提交回合命令
        for (const [player, commands] of playerCommands) {
            try {
                const result = this._battleSystem.submitRoundCommands(player, commands);
                LOG.log(`提交玩家 ${player} 第 ${currentRound} 回合的 ${commands.length} 个命令, 结果: ${result.success ? '成功' : '失败' + (result.error ? ' - ' + result.error : '')}`);

                this._commandIdCounter += commands.length;
            } catch (error) {
                LOG.error(`提交玩家 ${player} 第 ${currentRound} 回合命令失败:`, error);
            }
        }

        // 继续执行下一条命令
        if (this._commandQueue.length > 0) {
            setTimeout(() => {
                this.executeNextCommand();
            }, this._executionInterval);
        }
    }

    /**
     * 一次性获取所有命令集
     * @returns 转换后的命令数组
     */
    public getAllCommands(): CommandParam<keyof CommandParamMap>[] {
        // 使用默认命令数据的副本，避免修改原始数据
        const commandsCopy = [...DEFAULT_COMMANDS];

        LOG.log(`CommandExecutor: 开始过滤 ${commandsCopy.length} 条命令`);

        const validCommands = commandsCopy.filter(command => {
            if (this.isValidCommand(command)) {
                return true;
            } else {
                LOG.warn(`CommandExecutor: 跳过无效命令:`, command);
                return false;
            }
        });

        LOG.log(`CommandExecutor: 成功过滤出 ${validCommands.length} 条有效命令`);
        return validCommands;
    }

    /**
     * 处理所有命令
     */
    public executeAllCommands(): void {
        this.battleScene = battleScene.getBattleScene();
        if (!this.battleScene) {
            LOG.error('CommandExecutor: BattleScene 未初始化，无法发送命令');
            return;
        }

        LOG.log('CommandExecutor: 开始向BattleScene发送所有命令');

        try {
            // 获取所有转换后的命令
            const allCommands = this.getAllCommands();

            if (allCommands.length === 0) {
                LOG.warn('CommandExecutor: 没有可发送的命令');
                return;
            }

            // 调用BattleScene的批量处理方法
            this.battleScene.handleBattleCommandBatch(allCommands);

            LOG.log(`CommandExecutor: 成功向BattleScene发送 ${allCommands.length} 个命令`);
        } catch (error) {
            LOG.error('CommandExecutor: 向BattleScene发送命令时发生错误:', error);
        }
    }
}
